using System;
using System.Diagnostics;

using org.fourzoas.noise.model;
using org.fourzoas.noise.module;

namespace org.fourzoas.noise.model {
  /// <summary>
  /// Model that defines the surface of a plane.
  /// </summary>
  /// <remarks>
  /// <para>
  /// This model returns an ouput value from a noise module given the coordinates of an input value located on
  /// the surface of an (<em>x</em>, <em>z</em>) plane.
  /// </para>
  /// <para>
  /// To generate an output value, pass the (<em>x</em>, <em>z</em>) coordinates of an input value to the 
  /// <see cref="GetValue"/> method.
  /// </para>
  /// <para>
  /// This model is useful for creating:
  /// <list type="bullet">
  /// <item><description>two-dimensional textures</description></item>
  /// <item><description>terrain height maps for local areas</description></item>
  /// </list>
  /// </para>
  /// <para>
  /// This plane extends infinitely in both directions.
  /// </para>
  /// </remarks>
  public class Plane : Model {
    /// <summary>
    /// Default constructor.
    /// </summary>
    public Plane()
      : base() {
    }
    /// <summary>
    /// Constructor with a specific <see cref="Module"/>.
    /// </summary>
    /// <param name="module">The noise module that is used to generate the output.</param>
    public Plane(Module module)
      : base(module) {
    }
    /// <summary>
    /// Returns the output value from the noise module given the (<em>x</em>, <em>z</em>) coordinates
    /// of the specified input value located on the surface of the plane.
    /// </summary>
    /// <param name="coords">The <em>x</em> and <em>z</em> coordinate of the input value.</param>
    /// <returns>The output value from the noise module.</returns>
    /// <remarks>
    /// <para>
    /// This output value is generated by the noise module passed to the <see cref="Model.Module"/> property.
    /// </para>
    /// <h5>Preconditions</h5>
    /// <para>
    /// A noise module was passed to either the constructor or the <see cref="Model.Module"/> property.
    /// </para>
    /// </remarks>
    public override double GetValue(params double[] coords) {
      Debug.Assert(m_Module != null);
      Debug.Assert(coords.Length == 2);
      return m_Module.GetValue(coords[0], 0, coords[1]);
    }
  }
}
